package com.coszero.common.utils.gson;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import android.text.TextUtils;

import com.coszero.utils.utils.LogX;
import com.coszero.utils.utils.StringUtils;
import com.coszero.common.base.mvp.BaseModel;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Desc: google的Gson解析
 * com.google.code.gson:gson:2.8.2
 * <p>
 * Author xmqian
 * Email:xmqian93@163.com
 * Date: 2019/5/17
 * @version com.google.code.gson:gson:2.8.2
 */
public class GsonUtil {
    private static GsonBuilder gsonBuilder = null;

    private static Gson getGson() {
        GsonBuilder gsonBuilder = getGsonBuilder();
        return gsonBuilder.create();
    }

    @NonNull
    private static GsonBuilder getGsonBuilder() {
        if (gsonBuilder == null) {
            //忽略字符序列为零的
            gsonBuilder = new GsonBuilder().serializeNulls();
        }
        return gsonBuilder;
    }

    /**
     * 将对象转化为字符串
     */
    public static String toJsonStr(Object obj) {
        try {
            String jsonStr = getGson().toJson(obj);
            return jsonStr;
        } catch (Exception e) {
            e.printStackTrace();
            LogX.e(e.getMessage());
            return "";
        }
    }

    /**
     * json to object
     */
    public static <T> T fromJson(@Nullable String json, Class<T> clazz) {
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        try {
            return getGson().fromJson(json, clazz);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            LogX.e("json解析错误：" + e.getMessage() + "\n错误json: " + json);
            return null;
        }
    }

    public static <T> T parseGson(String jsonStr, Type clas) {
        try {
            return getGson().fromJson(jsonStr, clas);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            LogX.e("json解析错误：" + e.getMessage() + "\n错误json: " + jsonStr);
            return null;
        }
    }

    /**
     * 字符串转化为list
     *
     * @param listJson
     * @param type new TypeToken<ArrayList<CityBean>>() {}.getType()
     * @return
     */
    public static List getList(String listJson, Type type) {
        try {
            if (!StringUtils.isEmpty(listJson)) {
                List listBeans = getGson().fromJson(listJson, type);
                return listBeans;
            }
        } catch (Exception e) {
            LogX.e("GsonUtil->getPlazzList()", "解析数组json失败");
        }
        return null;
    }

    /**
     * 解析集合
     *
     * @param json json
     * @param clazz object
     * @param <T> t
     * @return Collection
     */
    public static <T> ArrayList<T> jsonToArrayList(String json, Class<T> clazz) {
        Type type = new TypeToken<ArrayList<JsonObject>>() {
        }.getType();
        ArrayList<JsonObject> jsonObjects = new Gson().fromJson(json, type);
        ArrayList<T> arrayList = new ArrayList<>();
        for (JsonObject jsonObject : jsonObjects) {
            arrayList.add(new Gson().fromJson(jsonObject, clazz));
        }
        return arrayList;
    }

    /**
     * Result<HistoryModel> listResult = GsonFrom.fromJsonObject(result, HistoryModel.class);
     * 解析泛型Object
     *
     * @param clazz 泛型
     * @param <T> 泛型类
     * @return
     */
    public static <T> BaseModel<T> fromJsonObject(String jsonStr, Class<T> clazz) {
        Type type = new ParameterizedTypeImpl(BaseModel.class, new Class[]{clazz});
        return parseGson(jsonStr, type);
    }

    /**
     * Result<List<CollectModel>> listResult = GsonFrom.fromJsonArray(result, CollectModel.class);
     * 解析泛型List
     *
     * @param clazz 泛型
     * @param <T> 泛型
     * @return
     */
    public static <T> BaseModel<List<T>> fromJsonArray(String jsonStr, Class<T> clazz) {
        // 生成List<T> 中的 List<T>
        Type listType = new ParameterizedTypeImpl(List.class, new Class[]{clazz});
        // 根据List<T>生成完整的Result<List<T>>
        Type type = new ParameterizedTypeImpl(BaseModel.class, new Type[]{listType});
        return parseGson(jsonStr, type);
    }
}
